package com.xlabs.server.DO;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.users.User;
import com.xlabs.client.DTO.QuestionDTO;

import javax.jdo.PersistenceManager;
import javax.jdo.annotations.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Question data object.
 */
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class QuestionDO {

    /**
     * Primary key.
     */
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    /**
     * The text comment.
     */
    @Persistent
    private String questionText;

    /**
     * The start time of video to which this question relates.
     */
    @Persistent
    private Integer startTime;

    /**
     * The end time of video to which this question relates. 
     */
    @Persistent
    private Integer endTime;

    /**
     * The video that has this comment.
     */
    @Persistent
    private Key video;

    /**
     * Replies to this comment.
     */
    @Persistent
    private List<Key> replies;

    /**
     * When created.
     */
    @Persistent
    private Date createdOn;

    /**
     * Created by user.
     */
    @Persistent
    private User createdBy;

    /**
     * Initializes an instance of TimedComment.
     *
     * @param questionText The comment.
     * @param startTime the start of corresponding video interval.
     * @param endTime the end of corresponding video interval.
     */
    public QuestionDO(String questionText, int startTime, int endTime, Date createdOn) {
        this.questionText = questionText;
        this.startTime = startTime;
        this.endTime = endTime;
        this.createdOn = createdOn;
    }

    /**
     * Gets the key.
     *
     * @return id.
     */
    public Key getKey() {
        return key;
    }

    /**
     * Sets the key.
     * @param key key.
     */
    public void setKey(Key key)
    {
        this.key = key;
    }

    /**
     * Gets comment.
     *
     * @return comment.
     */
    public String getQuestionText() {
        return questionText;
    }

    /**
     * Sets Comment.
     *
     * @param questionText The text comment.
     */
    public void setQuestionText(String questionText) {
        this.questionText = questionText;
    }

    /**
     * Gets video.
     *
     * @return video.
     */
    public Key getVideo() {
        return video;
    }

    /**
     * Sets video
     *
     * @param video video that has this comment.
     */
    public void setVideo(Key video) {
        this.video = video;
    }


    /**
     * Gets replies.
     * @return List of replies.
     */
    public List<Key> getReplies() {
        return replies;
    }

    /**
     * Sets replies.
     * @param replies List of replies.
     */
    public void setReplies(List<Key> replies) {
        this.replies = replies;
    }

    /**
     * Adds a reply.
     * @param replyKey reply key.
     */
    public void addReply(Key replyKey)
    {
        if (this.replies == null)
        {
            this.replies = new ArrayList<Key>();
        }
        this.replies.add(replyKey);
    }

    /**
     * Returns the encoded Key of this jdo as a string.
     * @return encoded key.
     */
    public String getEncodedKey() {
        return KeyFactory.keyToString(this.key);
    }

    /**
     * Returns all comments sorted by time
     *
     * @return result.
     */
    public static QuestionDTO[] getAllQuestions() {
        PersistenceManager pm = PMF.get().getPersistenceManager();

        try {
            String allQuestionsQuery = "SELECT FROM " + QuestionDO.class.getName() + " ORDER BY startTime ASC ";
            List<QuestionDO> allQuestions = (List<QuestionDO>) pm.newQuery(allQuestionsQuery).execute();

            return QuestionDO.toQuestionDTOArray(allQuestions);
        }
        finally {
            pm.close();
        }
    }

    /**
     * Gets createdOn.
     * @return time of creation.
     */
    public Date getCreatedOn() {
        return createdOn;
    }

    /**
     * Sets time of creation.
     * @param createdOn time of creation.
     */
    public void setCreatedOn(Date createdOn) {
        this.createdOn = createdOn;
    }

    /**
     * Gets createdBy.
     * @return creator.
     */
    public User getCreatedBy() {
        return createdBy;
    }

    /**
     * Sets createdBy.
     * @param createdBy creator.
     */
    public void setCreatedBy(User createdBy) {
        this.createdBy = createdBy;
    }

    /**
     * Gets {@link #startTime}
     * @return {@link #startTime}
     */
    public Integer getStartTime() {
        return startTime;
    }

    /**
     * Sets {@link #startTime}
     * @param startTime {@link #startTime}
     */
    public void setStartTime(Integer startTime) {
        this.startTime = startTime;
    }

    /**
     * Gets {@link #endTime}
     * @return {@link #endTime}
     */
    public Integer getEndTime() {
        return endTime;
    }

    /**
     * Sets {@link #endTime}
     * @param endTime {@link #endTime}
     */
    public void setEndTime(Integer endTime) {
        this.endTime = endTime;
    }

    /**
     * Converts an array of {@link com.xlabs.server.DO.QuestionDO} objects to an array of {@link QuestionDTO}
     * @param questionDOArray
     * @return
     */
    public static QuestionDTO[] toQuestionDTOArray(List<QuestionDO> questionDOArray) {
        QuestionDTO[] questionDTOs = new QuestionDTO[questionDOArray.size()];

        int index = 0;
        for (QuestionDO aQuestionDO : questionDOArray) {
            questionDTOs[index++] = aQuestionDO.toQuestionDTO();
        }

        return questionDTOs;
    }

    /**
     * Converts this objecto to CommentDTO.
     * @return com.xlabs.client.CommentDTO
     */
    public QuestionDTO toQuestionDTO() {
        QuestionDTO dto = new QuestionDTO(
                this.getQuestionText(),
                this.getStartTime(),
                this.getEndTime(),
                this.getCreatedOn());

        dto.setEncodedKey(this.getEncodedKey());
        dto.setCreatedBy(this.getCreatedBy().getNickname());
        
        return dto;
    }
}
